﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using RaisingStudio.SmallProgram.Library;
using Windows.Foundation;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;

namespace RaisingStudio.SmallProgram.Library.Internal
{
    public static class SmallProgramApplication
    {
        private static DispatcherTimer dispatcherTimer;
        private static object locker = new object();
        internal static Queue<InvokeHelper> mainThreadActions = new Queue<InvokeHelper>();
        private static Queue<InvokeHelper> queuedActions = new Queue<InvokeHelper>();

        internal static void BeginInvoke(InvokeHelper invokeDelegate)
        {
            // TODO:
            //Dispatcher.BeginInvoke(invokeDelegate, new object[0]);  
            invokeDelegate();
        }

        internal static void ClearDispatcherQueue()
        {
        }

        internal static BitmapSource CropBitmap(BitmapSource original, Primitive left, Primitive top, Primitive width, Primitive height)
        {
            BitmapImage bitmapImage = original as BitmapImage;
            if (bitmapImage != null)
            {
                ManualResetEvent manualResetEvent = new ManualResetEvent(false);
                Invoke(delegate
                {
                    if (bitmapImage.PixelWidth > 0)
                    {
                        manualResetEvent.Set();
                    }
                    else
                    {
                        bitmapImage.ImageOpened += delegate
                        {
                            manualResetEvent.Set();
                        };
                    }
                });
                manualResetEvent.WaitOne();
            }

            return (BitmapSource)InvokeWithReturn(delegate
            {
                if (left < 0)
                {
                    left = 0;
                }
                if (top < 0)
                {
                    top = 0;
                }
                if ((left + width) > original.PixelWidth)
                {
                    width = original.PixelWidth - left;
                }
                if ((top + height) > original.PixelHeight)
                {
                    height = original.PixelHeight - top;
                }
                Image image = new Image();
                image.Source = original;
                image.Measure(new Size((double)original.PixelWidth, (double)original.PixelHeight));
                image.Arrange(new Rect(0.0, 0.0, (double)original.PixelWidth, (double)original.PixelHeight));
                WriteableBitmap bitmap = new WriteableBitmap((int)width, (int)height);
                // TODO:
                //bitmap.Render(image, new TranslateTransform { X = (double)-left, Y = (double)-top });
                bitmap.Invalidate();
                return bitmap;
            });
        }

        private static void DispatchActions(object sender, EventArgs e)
        {
            lock (locker)
            {
                while (queuedActions.Count > 0)
                {
                    queuedActions.Dequeue()();
                }
            }
        }

        internal static string GetEntryAssemblyPath()
        {
            //return Assembly.GetExecutingAssembly().Location;
            // TODO:
            return null;
        }

        internal static Uri GetResourceUri(string resourceName)
        {
            return new Uri(string.Format("Resources/{0}", resourceName), UriKind.Relative);
        }

        internal static void Initialize()
        {
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(30.0);
            dispatcherTimer = timer;
            dispatcherTimer.Tick += new Windows.UI.Xaml.EventHandler(dispatcherTimer_Tick);
        }

        static void dispatcherTimer_Tick(object sender, object e)
        {
            // TODO:
            DispatchActions(sender, (EventArgs)e);
        }

        internal static void Invoke(InvokeHelper invokeDelegate)
        {
            // TODO:
            invokeDelegate();
        }

        internal static void InvokeInMainThread(InvokeHelper invokeDelegate)
        {
            mainThreadActions.Enqueue(invokeDelegate);
        }

        internal static object InvokeWithReturn(InvokeHelperWithReturn invokeDelegate)
        {
            // TODO:
            object result = null;
            return result;
        }

        internal static CoreDispatcher Dispatcher
        {
            get
            {
                return GraphicsWindow._dispatcher;
            }
        }

        internal static bool HasShutdown
        {
            get
            {
                return false;
            }
        }
    }
}

